const mongoose = require("mongoose");
const Auth = mongoose.model("auth");
const AuthVld = require("./auth.vld");
const { md5Handle, jwtSign, Resp } = require("../../config/utils");
const redis = require("../../config/redis");

class AuthCtrl {
  /**
   * @api {get} /auths 获取用户列表
   * @apiName auths_list
   * @apiGroup auths
   * 
   * @apiHeader {String} vf token 
   * 
   * @apiParam {String} pageNumber 页数
   * @apiParam {String} pageCount 每页个数
   * @apiSuccessExample 返回示例
      HTTP/1.1 200 OK
      {
        "code": 1,
        "msg": "获取用户成功!",
        "data": {
          "list": [],
          "count": 1
        }
      }
   * @apiErrorExample 错误示例
      HTTP/1.1 500 Internal Server Error
  */
  async getAuths(ctx, next) {
    let { pageCount = 10, pageNumber = 1 } = ctx.query;
    let auths = Auth.find({}, { __v: 0, password: 0 })
      .populate("role")
      .sort({ created_at: -1 })
      .skip((Number(pageNumber) - 1) * Number(pageCount))
      .limit(Number(pageCount))
    let [list, count] = await Promise.all([auths, Auth.countDocuments()])
    ctx.body = Resp(1, "获取用户成功！", {
      list, count
    })
  }
  /**
   * @api {post} /auths 新增用户
   * @apiName auths_add
   * @apiGroup auths
   * 
   * @apiHeader {String} vf token 
   * 
   * @apiParam {String} username 用户名
   * @apiParam {String} password 密码
   * @apiParam {String} nickName 昵称
   * @apiParam {String} role 角色
   * @apiSuccessExample 返回示例
      HTTP/1.1 200 OK
      {
        "code": 1,
        "msg": "创建用户成功！",
        "data": {}
      }
   * @apiErrorExample 错误示例
      HTTP/1.1 500 Internal Server Error
  */
  async createAuths(ctx, next) {
    let { username, password, nickName, role } = ctx.request.body;
    let validate = await AuthVld.createAuth(username, password, nickName, role);
    if (validate && validate.status === 0) {
      return (ctx.body = Resp(0, validate.msg, null));
    }
    password = md5Handle(password, username.slice(0, 4));
    let result = await Auth.create({ username, password, nickName, role });
    result = result.toObject();
    delete result.password;
    return (ctx.body = Resp(
      1,
      "创建用户成功！",
      result
    ));
  }
  /**
   * @api {delete} /auths 删除用户
   * @apiName auths_delete
   * @apiGroup auths
   * 
   * @apiHeader {String} vf token 
   * 
   * @apiParam {String} id 用户ID
   * @apiSuccessExample 返回示例
      HTTP/1.1 200 OK
      {
        "code": 1,
        "msg": "删除用户成功！",
        "data": null
      }
   * @apiErrorExample 错误示例
      HTTP/1.1 500 Internal Server Error
  */
  async removeAuth(ctx, next) {
    let { id } = ctx.params;

    if (!id) {
      return (ctx.body = Resp(0, "缺少参数！", null));
    }
    let result = await Auth.remove({ _id: id });
    if (result.ok === 1) {
      return (ctx.body = Resp(1, "删除用户成功！", null));
    } else {
      return (ctx.body = Resp(1, "删除用户失败！", null));
    }
  }
  /**
   * @api {post} /login 登陆
   * @apiName auths_login
   * @apiGroup auths 
   * 
   * @apiParam {String} username 用户名
   * @apiParam {String} password 密码
   * @apiSuccessExample 返回示例
      HTTP/1.1 200 OK
      {
        "code": 1,
        "msg": "登陆成功！",
        "data": {}
      }
   * @apiErrorExample 错误示例
      HTTP/1.1 500 Internal Server Error
  */
  async login(ctx, next) {
    let { username, password } = ctx.request.body;
    let validate = await AuthVld.login(username, password);
    if (validate && validate.status === 0) {
      return (ctx.body = Resp(0, validate.msg, null));
    }
    let result = await Auth.findOne({ username: username }).populate("role");
    if (!result) return (ctx.body = Resp(0, "不存在此用户！", null));
    let saltPassword = md5Handle(password, username.slice(0, 4));
    if (saltPassword != result.password)
      return (ctx.body = Resp(0, "用户名或密码错误！", null));
    let token = jwtSign(result);
    result = result.toObject();
    result["token"] = token;
    await redis.hsetAsync("loginInfo", String(result._id), token);
    delete result.password;
    return (ctx.body = Resp(
      1,
      "登陆成功！",
      result
    ));
  }
  /**
   * @api {post} /logout 注销
   * @apiName auths_logout
   * @apiGroup auths
   * 
   * @apiHeader {String} vf token 
   * 
   * @apiSuccessExample 返回示例
      HTTP/1.1 200 OK
      {
        "code": 1,
        "msg": "注销成功！",
        "data": {}
      }
   * @apiErrorExample 错误示例
      HTTP/1.1 500 Internal Server Error
  */
  async logout(ctx, next) {
    if (ctx.user) {
      let id = ctx.user.data._id;
      await redis.hdelAsync("loginInfo", String(id));
      return (ctx.body = Resp(1, "注销成功！", null));
    } else {
      return (ctx.body = Resp(0, "用户处理异常！", null));
    }
  }
}

module.exports = new AuthCtrl();
